/*
 * SwatchesWidget.h - Class for selecting a color swatch.
 *
 * Author: Patrick O'Leary
 * Created: December 9, 2007
 * Copyright: 2007
 */
#ifndef SWATCHESWIDGET_INCLUDED
#define SWATCHESWIDGET_INCLUDED

#include <GL/gl.h>

/* Vrui includes */
#include <GLMotif/Container.h>
#include <GLMotif/Event.h>
#include <GLMotif/Types.h>
#include <GLMotif/Widget.h>
#include <Misc/CallbackList.h>


static GLubyte swatchColors[279][3] = {
	{255, 255, 255}, {204, 255, 255}, {204, 204, 255}, {204, 204, 255}, {204, 204, 255}, {204, 204, 255}, {204, 204, 255}, {204, 204, 255}, {204, 204, 255},
	{204, 204, 255}, {204, 204, 255}, {255, 204, 255}, {255, 204, 204}, {255, 204, 204}, {255, 204, 204}, {255, 204, 204}, {255, 204, 204}, {255, 204, 204},
	{255, 204, 204}, {255, 204, 204}, {255, 204, 204}, {255, 255, 204}, {204, 255, 204}, {204, 255, 204}, {204, 255, 204}, {204, 255, 204}, {204, 255, 204},
	{204, 255, 204}, {204, 255, 204}, {204, 255, 204}, {204, 255, 204}, {204, 204, 204}, {153, 255, 255}, {153, 204, 255}, {153, 153, 255}, {153, 153, 255},
	{153, 153, 255}, {153, 153, 255}, {153, 153, 255}, {153, 153, 255}, {153, 153, 255}, {204, 153, 255}, {255, 153, 255}, {255, 153, 204}, {255, 153, 153},
	{255, 153, 153}, {255, 153, 153}, {255, 153, 153}, {255, 153, 153}, {255, 153, 153}, {255, 153, 153}, {255, 204, 153}, {255, 255, 153}, {204, 255, 153},
	{153, 255, 153}, {153, 255, 153}, {153, 255, 153}, {153, 255, 153}, {153, 255, 153}, {153, 255, 153}, {153, 255, 153}, {153, 255, 204}, {204, 204, 204},
	{102, 255, 255}, {102, 204, 255}, {102, 153, 255}, {102, 102, 255}, {102, 102, 255}, {102, 102, 255}, {102, 102, 255}, {102, 102, 255}, {153, 102, 255},
	{204, 102, 255}, {255, 102, 255}, {255, 102, 204}, {255, 102, 153}, {255, 102, 102}, {255, 102, 102}, {255, 102, 102}, {255, 102, 102}, {255, 102, 102},
	{255, 153, 102}, {255, 204, 102}, {255, 255, 102}, {204, 255, 102}, {153, 255, 102}, {102, 255, 102}, {102, 255, 102}, {102, 255, 102}, {102, 255, 102},
	{102, 255, 102}, {102, 255, 153}, {102, 255, 204}, {153, 153, 153}, { 51, 255, 255}, { 51, 204, 255}, { 51, 153, 255}, { 51, 102, 255}, { 51,  51, 255},
	{ 51,  51, 255}, { 51,  51, 255}, {102,  51, 255}, {153,  51, 255}, {204,  51, 255}, {255,  51, 255}, {255,  51, 204}, {255,  51, 153}, {255,  51, 102},
	{255,  51,  51}, {255,  51,  51}, {255,  51,  51}, {255, 102,  51}, {255, 153,  51}, {255, 204,  51}, {255, 255,  51}, {204, 255,  51}, {153, 244,  51},
	{102, 255,  51}, { 51, 255,  51}, { 51, 255,  51}, { 51, 255,  51}, { 51, 255, 102}, { 51, 255, 153}, { 51, 255, 204}, {153, 153, 153}, {  0, 255, 255},
	{  0, 204, 255}, {  0, 153, 255}, {  0, 102, 255}, {  0,  51, 255}, {  0,   0, 255}, { 51,   0, 255}, {102,   0, 255}, {153,   0, 255}, {204,   0, 255},
	{255,   0, 255}, {255,   0, 204}, {255,   0, 153}, {255,   0, 102}, {255,   0,  51}, {255,   0,   0}, {255,  51,   0}, {255, 102,   0}, {255, 153,   0},
	{255, 204,   0}, {255, 255,   0}, {204, 255,   0}, {153, 255,   0}, {102, 255,   0}, { 51, 255,   0}, {  0, 255,   0}, {  0, 255,  51}, {  0, 255, 102},
	{  0, 255, 153}, {  0, 255, 204}, {102, 102, 102}, {  0, 204, 204}, {  0, 204, 204}, {  0, 153, 204}, {  0, 102, 204}, {  0,  51, 204}, {  0,   0, 204},
	{ 51,   0, 204}, {102,   0, 204}, {153,   0, 204}, {204,   0, 204}, {204,   0, 204}, {204,   0, 204}, {204,   0, 153}, {204,   0, 102}, {204,   0,  51},
	{204,   0,   0}, {204,  51,   0}, {204, 102,   0}, {204, 153,   0}, {204, 204,   0}, {204, 204,   0}, {204, 204,   0}, {153, 204,   0}, {102, 204,   0},
	{ 51, 204,   0}, {  0, 204,   0}, {  0, 204,  51}, {  0, 204, 102}, {  0, 204, 153}, {  0, 204, 204}, {102, 102, 102}, {  0, 153, 153}, {  0, 153, 153},
	{  0, 153, 153}, {  0, 102, 153}, {  0,  51, 153}, {  0,   0, 153}, { 51,   0, 153}, {102,   0, 153}, {153,   0, 153}, {153,   0, 153}, {153,   0, 153},
	{153,   0, 153}, {153,   0, 153}, {153,   0, 102}, {153,   0,  51}, {153,   0,   0}, {153,  51,   0}, {153, 102,   0}, {153, 153,   0}, {153, 153,   0},
	{153, 153,   0}, {153, 153,   0}, {153, 153,   0}, {102, 153,   0}, { 51, 153,   0}, {  0, 153,   0}, {  0, 153,  51}, {  0, 153, 102}, {  0, 153, 153},
	{  0, 153, 153}, { 51,  51,  51}, {  0, 102, 102}, {  0, 102, 102}, {  0, 102, 102}, {  0, 102, 102}, {  0,  51, 102}, {  0,   0, 102}, { 51,   0, 102},
	{102,   0, 102}, {102,   0, 102}, {102,   0, 102}, {102,   0, 102}, {102,   0, 102}, {102,   0, 102}, {102,   0, 102}, {102,   0,  51}, {102,   0,   0},
	{102,  51,   0}, {102, 102,   0}, {102, 102,   0}, {102, 102,   0}, {102, 102,   0}, {102, 102,   0}, {102, 102,   0}, {102, 102,   0}, { 51, 102,   0},
	{  0, 102,   0}, {  0, 102,  51}, {  0, 102, 102}, {  0, 102, 102}, {  0, 102, 102}, {  0,   0,   0}, {  0,  51,  51}, {  0,  51,  51}, {  0,  51,  51},
	{  0,  51,  51}, {  0,  51,  51}, {  0,   0,  51}, { 51,   0,  51}, { 51,   0,  51}, { 51,   0,  51}, { 51,   0,  51}, { 51,   0,  51}, { 51,   0,  51},
	{ 51,   0,  51}, { 51,   0,  51}, { 51,   0,  51}, { 51,   0,   0}, { 51,  51,   0}, { 51,  51,   0}, { 51,  51,   0}, { 51,  51,   0}, { 51,  51,   0},
	{ 51,  51,   0}, { 51,  51,   0}, { 51,  51,   0}, {  0,  51,   0}, {  0,  51,  51}, {  0,  51,  51}, {  0,  51,  51}, {  0,  51,  51}, { 51,  51,  51}
};

class SwatchesWidget : public GLMotif::Widget {
public:
	SwatchesWidget(const char* _name, GLMotif::Container* _parent, bool _manageChild=true);
	virtual ~SwatchesWidget(void);
	virtual GLMotif::Vector calcNaturalSize(void) const;
	virtual void draw(GLContextData& contextData) const;
	void drawSwatchesWidget(GLfloat x, GLfloat y, GLfloat z, GLfloat width, GLfloat height) const;
	void drawSwatchesWidgetArea(void) const;
	void drawMargin(void) const;
	virtual bool findRecipient(GLMotif::Event& event);
	void setBounds(GLfloat width, GLfloat height);
	Misc::CallbackList& getColorChangedCallbacks(void);
	GLubyte* getColorForCell(int column, int row) const;
	GLubyte* getColorForLocation(double x, double y);
	float* getCurrentColor(void);
	void setMarginWidth(GLfloat _marginWidth);
	void setPreferredSize(const GLMotif::Vector& _preferredSize);
	void setPreferredSwatchSize(void);
	void setSwatchesSize(void);
	virtual void pointerButtonDown(GLMotif::Event& event);
	virtual void pointerButtonUp(GLMotif::Event& event);
	virtual void pointerMotion(GLMotif::Event& event);
	virtual void resize(const GLMotif::Box& _exterior);
private:
	GLMotif::Box swatchesAreaBox;
	Misc::CallbackList colorChangedCallbacks;
	bool isSelected;
	GLfloat marginWidth;
	GLMotif::Vector preferredSize;
	float* currentColor;
	int numberOfColumns;
	int numberOfRows;
	double preferredSwatchSize[2];
	double defaultSwatchSize[2];
	double gap[2];
	double swatchSize[2];
};

#endif
